/***********************************************************************************************************
============================================================================================================
 Bits Download Manager
 http://www.codeplex.com/BITSDownloadMgr

 Component:BITSDownloadMgr.Interop
 File Name:CopyFile.cs
 
 
============================================================================================================
 Copyright (C) 2004-2007 Microsoft Corporation

 This source is subject to the Microsoft Public License (Ms-PL).
 See http:www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
 All other rights reserved.

 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
 OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
 LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
 FITNESS FOR A PARTICULAR PURPOSE.
============================================================================================================
***********************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using BitsDownloadMgr.Interop;
namespace BitsDownloadMgr.Interop
{
	public sealed class CopyFile : IDisposable
	{
		private IBackgroundCopyFile _nativeObject;
        
		internal CopyFile(IBackgroundCopyFile nativeObject)
		{
			_nativeObject = nativeObject;
			UpdateProgress(); 
		}

        public event EventHandler FileProgress;
        private void OnFileProgress()
        {
            if (FileProgress != null)
            {
                FileProgress.BeginInvoke(this, new EventArgs(), null, null); 
            }
        }

        /// <summary>
        /// Refresh timer.  Created without being enabled.  
        /// </summary>
        System.Threading.Timer _refreshTimer;

        private void fileProgressTimerCallback(object state)
        {
            UpdateProgress(); 
        }
        /// <summary>
        /// Enables automatic background updates for the file.  
        /// Progress updates will be delivered via the FileProgress event.  
        /// </summary>
        /// <remarks>Max value is 120 (2 minutes)</remarks>
        /// <param name="progressRefreshTime">File progress refresh time in seconds.</param>
        public void EnableProgressUpdates(int progressRefreshTime)
        {
            //validate the refresh time is less than 120 seconds.  
            if (progressRefreshTime > 120)
            {
                throw new ArgumentException("ProgressRefreshTime must be less than 120 (2 minutes)"); 
            }
            if(_refreshTimer == null)
            {
                _refreshTimer = new System.Threading.Timer(
                    new System.Threading.TimerCallback(fileProgressTimerCallback), null, 
                    System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
            }
            _refreshTimer.Change(0, progressRefreshTime * 1000);
        }

        public void DisableProgressUpdates()
        {
            if(_refreshTimer != null)
            {
                _refreshTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); 
            }
        }
		//TODO: Implement properties for IBackgroundCopyError 
		#region Properties
		public string LocalName
		{
			get
			{
				string locName;
				_nativeObject.GetLocalName(out locName);
				return locName; 
			}
		}
		public string RemoteName
		{
			get
			{
				string remName;
				_nativeObject.GetRemoteName(out remName);
				return remName; 
			}
		}

		public FileProgress Progress
		{
			get
			{
				_BG_FILE_PROGRESS nativeFileProgress;
				_nativeObject.GetProgress(out nativeFileProgress);
				return new FileProgress(nativeFileProgress); 
			}
		}

		public ulong BytesTotal
		{
			get 
			{ 
				return _cachedProgress.BytesTotal; 
			}
		}
		public ulong BytesTransferred
		{
			get
			{
				return _cachedProgress.BytesTransferred;
			}
		}
		public bool Completed
		{
			get
			{
				return _cachedProgress.Completed; 
			}
		}
		public decimal PercentComplete
		{
			get 
			{
				return _cachedProgress.PercentComplete; 
			}
		}
		#endregion 
		#region CleanUp Code
		#region IDisposable Members

		void IDisposable.Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		#endregion

        
        private void Dispose(bool disposing)
		{
            if (disposing)
            {
                if (_refreshTimer != null)
                {
                    _refreshTimer.Dispose();
                }
                if (_nativeObject != null)
                {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(_nativeObject);
                }
            }
		}

		~CopyFile()
		{
			Dispose(false);
		}
		#endregion

		#region IUpdateProgress Members

		private FileProgress _cachedProgress = new FileProgress(new _BG_FILE_PROGRESS());
		private FileProgress _previousProgress; 
		public void UpdateProgress()
		{
			_previousProgress = _cachedProgress;
			_cachedProgress = Progress;
			if (
				_previousProgress.BytesTotal != _cachedProgress.BytesTotal || 
				_previousProgress.BytesTransferred != _cachedProgress.BytesTransferred)
			{
                //_cachedProgress = _previousProgress; 

                OnFileProgress();
                if (_cachedProgress.Completed)
                {
                    //no more progress updates are required.  Disable them.  
                    DisableProgressUpdates(); 
                }
			}
			
		}

		#endregion


}
}

